package com.ling.sdk.app


import android.support.annotation.CallSuper
import android.support.multidex.MultiDexApplication
import com.alibaba.android.arouter.launcher.ARouter
import com.ling.sdk.utils.Cache
import com.ling.sdk.BuildConfig
import com.ling.sdk.live.LiveManager
import com.ling.sdk.utils.ProcessUtil.isMainProcess
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.newFixedThreadPoolContext
import me.jessyan.autosize.AutoSizeConfig
import me.yokeyword.fragmentation.Fragmentation
import java.util.*

/**
 * Created by ALing on 2018/7/26 0026.
 */
const val isDebug = BuildConfig.DEBUG_MODE

abstract class App : MultiDexApplication(), ISDK {

    companion object {
        internal val Background = newFixedThreadPoolContext(2, "bg")
        lateinit var app: App
        private val sdks = ArrayList<ISDK>()
        @JvmStatic
        fun addSDK(sdk: ISDK) {
            sdks.add(sdk)
        }

    }

    override fun onCreate() {
        super.onCreate()
        app = this
        //============core==================//
        if (isDebug) {           // 这两行必须写在init之前，否则这些配置在init过程中将无效
            ARouter.openLog();     // 打印日志
            ARouter.openDebug();   // 开启调试模式(如果在InstantRun模式下运行，必须开启调试模式！线上版本需要关闭,否则有安全风险)
        }
        ARouter.init(this)
        //===================core==============//

        onSDKLoad()
        sdks.dispatch { onMultiProcessCreate() }
        sdks.dispatch { launch(Background) { onAsyncMultiProcessCreate() } }

        //下面是主进程的初始化，避免其他进程也初始化这些数据，造成不必要的资源浪
        if (!isMainProcess(app)) return
        sdks.dispatch { onInitSdk() }
        sdks.dispatch { launch(Background) { onAsyncInitSdk() } }
        sdks.clear()

        registerActivityLifecycleCallbacks(ActivityStack)
        registerActivityLifecycleCallbacks(LiveManager)
    }


    @CallSuper
    open fun onSDKLoad() {
        addSDK(this)
        val componentSDks = ARouter.getInstance().build(IComponentInit.NAME).navigation() as? IComponentInit
        componentSDks?.getComponentInitService()?.also { sdks.addAll(it) }
    }

    override fun onMultiProcessCreate() {}
    override fun onAsyncMultiProcessCreate() {}
    override fun onAsyncInitSdk() {}
    override fun onInitSdk() {

        AutoSizeConfig.getInstance().isCustomFragment = true

        Fragmentation.builder()
                // 显示悬浮球 ; 其他Mode:SHAKE: 摇一摇唤出   NONE：隐藏
                .stackViewMode(Fragmentation.BUBBLE)
                .debug(BuildConfig.DEBUG)
                // 更多查看wiki或demo
                .install()

        Cache.init(this)
    }


    private fun ArrayList<ISDK>.dispatch(call: () -> Unit) {
        forEach { call.invoke() }
    }


}